package controllers

import (
	"baokaobang/datasourse"
	"baokaobang/models"
	"baokaobang/utils"
	"fmt"
	"strings"
	"unicode/utf8"

	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/sessions"
)

type Label struct {
	Ctx iris.Context
}

// 用户创建标签
func (c *Label) PostCreate() interface{} {
	channel := c.Ctx.PostValue("channel")
	labelIds := c.Ctx.PostValue("labelIds")
	labelNames := c.Ctx.PostValue("labelNames")

	labelIdList := strings.Split(labelIds, ",")
	labelNameList := strings.Split(labelNames, ",")

	if len(channel) <= 0 {
		return utils.CommonRes(1000, "请提供渠道", "")
	}

	var userId int64
	if strings.EqualFold(channel, "wechat") {
		token := c.Ctx.GetHeader("token")

		//解析token
		claims, err := utils.ParseToken(token)
		if err != nil {
			return utils.CommonRes(20001, fmt.Sprintf("解析token出错：%s", err.Error()), "")
		}
		userId = utils.Atoi64(claims.Id)
	} else {
		session := sessions.Get(c.Ctx)
		userId, _ = session.GetInt64(fmt.Sprintf("%sUserId", channel))
	}

	db, err := datasourse.NewMasterOrm()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}

	sess := db.NewSession()
	defer sess.Close()
	err = sess.Begin()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("数据库事务开启失败：%s", err.Error()), "")
	}

	user := new(models.User)
	_, err = sess.ID(userId).Get(user)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}

	college := new(models.College)
	if user.UserType == 2 {
		if user.CollegeId <= 0 {
			return utils.CommonRes(1000, "用户院校信息异常", "")
		}
		_, err = sess.ID(user.CollegeId).Get(college)
		if err != nil {
			return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
		}
		if college.UniversityId <= 0 {
			return utils.CommonRes(1000, "用户大学信息异常", "")
		}
	}

	labelCount, err := sess.Table(new(models.UserLabel)).Where("`user_id` = ?", userId).Count()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}
	labelIdCount := 0
	labelNameCount := 0
	for _, labelId := range labelIdList {
		labelId = strings.TrimSpace(labelId)
		if len(labelId) > 0 {
			labelIdCount++
		}
	}
	for _, labelName := range labelNameList {
		labelName = strings.TrimSpace(labelName)
		if len(labelName) > 0 {
			labelNameCount++
		}
	}
	totalCount := int(labelCount) + labelIdCount + labelNameCount
	if totalCount > 5 {
		return utils.CommonRes(1000, "最多添加5个标签", "")
	}

	if user.UserType == 1 {
		if len(labelIdList) <= 0 {
			utils.CommonRes(1000, "至少要选择1个系统标签", "")
		}
		if len(labelNameList) <= 0 {
			utils.CommonRes(1000, "至少要添加1个自定义标签", "")
		}
	} else {
		selectedCount := len(labelIdList) + len(labelNameList)
		if selectedCount < 2 {
			utils.CommonRes(1000, "至少要选择2个标签", "")
		}
	}

	for _, name := range labelNameList {
		name = strings.TrimSpace(name)
		if len(name) > 0 {
			if utf8.RuneCountInString(name) > 8 {
				return utils.CommonRes(1000, "标签名不能超过8个字符", "")
			}

			var labelId int64

			label := new(models.Label)
			ok, err := sess.Where("`name` = ?", name).Get(label)
			if err != nil {
				return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
			}
			if ok {
				labelId = label.Id
			} else {
				newLabel := new(models.Label)
				newLabel.Name = name
				newLabel.MType = 3
				_, err = sess.InsertOne(newLabel)
				if err != nil {
					return utils.CommonRes(1000, fmt.Sprintf("添加失败：%s", err.Error()), "")
				}
				labelId = newLabel.Id
			}

			userLabel := new(models.UserLabel)
			userLabel.UserId = userId
			userLabel.LabelId = labelId
			_, err = sess.InsertOne(userLabel)
			if err != nil {
				return utils.CommonRes(1000, fmt.Sprintf("添加失败：%s", err.Error()), "")
			}

			if user.UserType == 2 {
				collegeLabel := new(models.CollegeLabel)
				collegeLabel.CollegeId = college.Id
				collegeLabel.LabelId = labelId
				_, err = sess.InsertOne(collegeLabel)
				if err != nil {
					return utils.CommonRes(1000, fmt.Sprintf("添加失败：%s", err.Error()), "")
				}

				universityLabel := new(models.UniversityLabel)
				universityLabel.UniversityId = college.UniversityId
				universityLabel.LabelId = labelId
				_, err = sess.InsertOne(universityLabel)
				if err != nil {
					return utils.CommonRes(1000, fmt.Sprintf("添加失败：%s", err.Error()), "")
				}
			}
		}
	}

	for _, labelId := range labelIdList {
		labelId = strings.TrimSpace(labelId)
		if len(labelId) > 0 {
			userLabel := new(models.UserLabel)
			userLabel.UserId = userId
			userLabel.LabelId = utils.Atoi64(labelId)
			_, err = sess.InsertOne(userLabel)
			if err != nil {
				return utils.CommonRes(1000, fmt.Sprintf("添加失败：%s", err.Error()), "")
			}

			if user.UserType == 2 {
				collegeLabel := new(models.CollegeLabel)
				collegeLabel.CollegeId = college.Id
				collegeLabel.LabelId = utils.Atoi64(labelId)
				_, err = sess.InsertOne(collegeLabel)
				if err != nil {
					return utils.CommonRes(1000, fmt.Sprintf("添加失败：%s", err.Error()), "")
				}

				universityLabel := new(models.UniversityLabel)
				universityLabel.UniversityId = college.UniversityId
				universityLabel.LabelId = utils.Atoi64(labelId)
				_, err = sess.InsertOne(universityLabel)
				if err != nil {
					return utils.CommonRes(1000, fmt.Sprintf("添加失败：%s", err.Error()), "")
				}
			}
		}
	}

	sess.Commit()

	return utils.CommonRes(20000, "添加成功", "")
}

// 获取用户标签
func (c *Label) PostList() interface{} {
	channel := c.Ctx.PostValue("channel")

	if len(channel) <= 0 {
		return utils.CommonRes(1000, "请提供渠道", "")
	}

	var userId int64
	if strings.EqualFold(channel, "wechat") {
		token := c.Ctx.GetHeader("token")

		//解析token
		claims, err := utils.ParseToken(token)
		if err != nil {
			return utils.CommonRes(20001, fmt.Sprintf("解析token出错：%s", err.Error()), "")
		}
		userId = utils.Atoi64(claims.Id)
	} else {
		session := sessions.Get(c.Ctx)
		userId, _ = session.GetInt64(fmt.Sprintf("%sUserId", channel))
	}

	db, err := datasourse.NewMasterOrm()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}

	userLabelList := make([]models.UserLabelObj, 0)
	err = db.Table(new(models.UserLabel)).Alias("ul").
		Join("INNER", []string{"label", "l"}, "ul.label_id = l.id").
		Where("ul.user_id = ?", userId).Find(&userLabelList)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法获取用户标签：%s", err.Error()), "")
	}

	return utils.CommonRes(20000, "成功获取用户标签", userLabelList)
}

// 获取展示标签
func (c *Label) PostShow() interface{} {
	db, err := datasourse.NewMasterOrm()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}

	labelList := make([]models.Label, 0)
	err = db.Table(new(models.Label)).Where("`m_type` = 2").Find(&labelList)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法获取展示标签：%s", err.Error()), "")
	}

	return utils.CommonRes(20000, "成功获取展示标签", labelList)
}

// 获取匹配标签
func (c *Label) PostMatch() interface{} {
	db, err := datasourse.NewMasterOrm()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}

	labelList := make([]models.Label, 0)
	err = db.Table(new(models.Label)).Where("`m_type` = 1").Find(&labelList)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法获取匹配标签：%s", err.Error()), "")
	}

	return utils.CommonRes(20000, "成功获取匹配标签", labelList)
}

// 删除标签
func (c *Label) PostDel() interface{} {
	id := c.Ctx.PostValue("id")
	channel := c.Ctx.PostValue("channel")

	if len(id) <= 0 {
		return utils.CommonRes(1000, "请提供要删除的标签id", "")
	}
	if len(channel) <= 0 {
		return utils.CommonRes(1000, "请提供渠道", "")
	}

	var userId int64
	if strings.EqualFold(channel, "wechat") {
		token := c.Ctx.GetHeader("token")
		claims, err := utils.ParseToken(token)
		if err != nil {
			return utils.CommonRes(1000, fmt.Sprintf("解析token出错：%s", err.Error()), "")
		}
		userId = utils.Atoi64(claims.Id)
	} else {
		session := sessions.Get(c.Ctx)
		userId, _ = session.GetInt64(fmt.Sprintf("%sUserId", channel))
	}

	db, err := datasourse.NewMasterOrm()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}

	sess := db.NewSession()
	defer sess.Close()
	err = sess.Begin()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("数据库事务开启失败：%s", err.Error()), "")
	}

	user := new(models.User)
	_, err = sess.ID(userId).Get(user)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}

	college := new(models.College)
	_, err = sess.ID(user.CollegeId).Get(college)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}

	userLabel := new(models.UserLabel)
	ok, err := sess.ID(id).Get(userLabel)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}
	if !ok {
		return utils.CommonRes(20000, "标签已删除", "")
	}

	label := new(models.Label)
	_, err = sess.ID(userLabel.LabelId).Get(label)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}
	if label.MType == 1 {
		return utils.CommonRes(1000, "系统标签不允许删除", "")
	}

	_, err = sess.ID(id).Delete(userLabel)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("删除失败：%s", err.Error()), "")
	}

	if user.UserType > 1 {
		collegeLabel := new(models.CollegeLabel)
		sess.Where("`college_id` = ? and `label_id` = ?", college.Id, userLabel.LabelId).Get(collegeLabel)
		sess.ID(collegeLabel.Id).Delete(collegeLabel)

		universityLabel := new(models.UniversityLabel)
		sess.Where("`university_id` = ? and `label_id` = ?", college.UniversityId, userLabel.LabelId).Get(universityLabel)
		sess.ID(universityLabel.Id).Delete(universityLabel)
	}

	sess.Commit()

	return utils.CommonRes(20000, "成功删除", "")
}
